"""
定时主动服务
实现定时任务调度，定期分析用户行为并发送主动推荐
"""

from typing import Dict, Any, List
from datetime import datetime
import asyncio
import logging
from uuid import UUID

from src.services.proactive_service import ProactiveService
from src.models.user import User
from src.utils.logging import get_logger
from src.config.database import get_db

logger = get_logger(__name__)


class ScheduledProactiveService:
    """定时主动服务类"""
    
    def __init__(self):
        self.proactive_service = ProactiveService()
        self.running = False
    
    async def start_scheduling(self):
        """
        启动定时任务调度
        """
        self.running = True
        logger.info("启动定时主动服务调度器")
        
        while self.running:
            try:
                await self._execute_scheduled_tasks()
                # 每小时执行一次
                await asyncio.sleep(3600)
            except Exception as e:
                logger.error(f"执行定时任务时出错: {e}")
                # 出错后等待一段时间再继续
                await asyncio.sleep(60)
    
    def stop_scheduling(self):
        """
        停止定时任务调度
        """
        self.running = False
        logger.info("停止定时主动服务调度器")
    
    async def _execute_scheduled_tasks(self):
        """
        执行定时任务
        """
        logger.info("开始执行定时主动服务任务")
        
        try:
            # 获取活跃用户
            active_users = await self._get_active_users()
            logger.info(f"获取到 {len(active_users)} 个活跃用户")
            
            # 为每个用户生成并发送推荐
            for user in active_users:
                try:
                    await self._process_user_recommendations(user)
                except Exception as e:
                    logger.error(f"处理用户 {user.id} 的推荐时出错: {e}")
            
            logger.info("定时主动服务任务执行完成")
        except Exception as e:
            logger.error(f"执行定时任务时出错: {e}")
    
    async def _get_active_users(self) -> List[User]:
        """
        获取活跃用户列表
        
        Returns:
            活跃用户列表
        """
        try:
            # 获取最近7天有活动的用户
            db_generator = get_db()
            db = next(db_generator)
            # 这里应该查询最近有活动的用户
            # 简化实现，获取所有用户
            users = db.query(User).all()
            return users
        except Exception as e:
            logger.error(f"获取活跃用户失败: {e}")
            return []
    
    async def _process_user_recommendations(self, user: User):
        """
        处理单个用户的推荐
        
        Args:
            user: 用户对象
        """
        try:
            user_id = UUID(str(user.id))
            
            # 生成主动推荐
            recommendations = await self.proactive_service.generate_proactive_recommendations(
                user_id, limit=3
            )
            
            # 发送推荐通知
            for recommendation in recommendations:
                # 添加发送时间检查，避免在用户不活跃时间发送
                if await self._should_send_notification(user, recommendation):
                    success = await self.proactive_service.send_proactive_notification(
                        user_id, recommendation
                    )
                    
                    if success:
                        logger.info(f"成功向用户 {user.id} 发送推荐: {recommendation.get('title')}")
                    else:
                        logger.warning(f"向用户 {user.id} 发送推荐失败: {recommendation.get('title')}")
                
                # 添加延迟避免发送过于频繁
                await asyncio.sleep(1)
                
        except Exception as e:
            logger.error(f"处理用户 {user.id} 的推荐时出错: {e}")
    
    async def _should_send_notification(self, user: User, recommendation: Dict[str, Any]) -> bool:
        """
        判断是否应该发送通知
        
        Args:
            user: 用户对象
            recommendation: 推荐内容
            
        Returns:
            是否应该发送通知
        """
        try:
            # 检查推荐类型
            recommendation_type = recommendation.get("type", "")
            
            # 对于时间相关的推荐，检查是否在合适的时间
            if recommendation_type == "reminder":
                preferred_time = recommendation.get("metadata", {}).get("preferred_time", "")
                # 这里可以实现更复杂的时间检查逻辑
                # 简化实现，允许发送
                return True
            
            # 对于上下文相关的推荐，检查时间上下文
            elif recommendation_type == "context":
                time_context = recommendation.get("metadata", {}).get("time_context", "")
                current_hour = datetime.now().hour
                
                if time_context == "morning" and 8 <= current_hour <= 10:
                    return True
                elif time_context == "afternoon" and 14 <= current_hour <= 16:
                    return True
                elif time_context == "evening" and 19 <= current_hour <= 21:
                    return True
                # 其他时间上下文默认发送
                elif not time_context:
                    return True
                else:
                    return False
            
            # 其他类型的推荐默认发送
            return True
        except Exception as e:
            logger.error(f"判断是否发送通知时出错: {e}")
            # 出错时默认发送
            return True